package com.ruoyi.flowable.interceptor;

import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.flowable.engine.IdentityService;
import org.flowable.engine.ManagementService;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngines;
import org.flowable.engine.impl.IdentityServiceImpl;
import org.flowable.idm.api.Group;
import org.flowable.idm.api.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.flowable.commond.DeleteMembershipByUserIdCmd;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.domain.SysUserPost;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysUserService;

@Intercepts({
        @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class })
})
public class SQLInterceptor implements Interceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(SQLInterceptor.class);

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //获取返回值，若执行的为插入操作，程序会将id注入到对应的对象
        Object object = invocation.proceed();
        IdentityService identityService = SpringUtils.getBean(IdentityService.class);
        Object[] args = invocation.getArgs();
        MappedStatement ms = (MappedStatement) args[0];
        String id = ms.getId();
        if (id.contains("SysUserPostMapper")) {
            SyncSysUserPost(args, identityService);
        } else if (id.contains("SysUserMapper")) {
            SyncSysUser(args, identityService);
        } else if (id.contains("SysPostMapper")) {
            SyncSysPost(args, identityService);
        }
        return object;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }

    public void SyncSysUser(Object[] args, IdentityService identityService) {
        MappedStatement ms = (MappedStatement) args[0];
        String id = ms.getId();
        Object userObject = args[1];
        // 包含deleteUserById与deleteUserByIds两个方法
        if (id.contains("deleteUserById")) {
            if (userObject instanceof Map) {
                Map userIds = (Map) userObject;
                Long[] ids = (Long[]) userIds.get("array");
                for (Long userId : ids) {
                    User flowableUser = identityService.createUserQuery().userFirstName(userId.toString()).singleResult();
                    if (flowableUser != null) {
                        identityService.deleteUser(flowableUser.getId());
                    }
                }
            }
        } else if (id.contains("updateUser")) {
            if (userObject instanceof SysUser) {
                SysUser sysUser = (SysUser) userObject;
                User flowableUser = identityService.createUserQuery().userId(sysUser.getLoginName()).singleResult();
                if (flowableUser == null) {
                    flowableUser = identityService.newUser(sysUser.getLoginName());
                } else {
                    flowableUser.setId(sysUser.getLoginName());
                }
                flowableUser.setDisplayName(sysUser.getUserName());
                flowableUser.setEmail(sysUser.getEmail());
                //PWD_ 存放 用户电话号
                flowableUser.setPassword(sysUser.getPhonenumber());
                //FIRST_ 存放 用户ID
                flowableUser.setFirstName(sysUser.getUserId().toString());
                //LAST_存放部门ID
                flowableUser.setLastName(sysUser.getDeptId().toString());
                identityService.saveUser(flowableUser);
            }
        } else if (id.contains("insertUser")) {
            if (userObject instanceof SysUser) {
                SysUser sysUser = (SysUser) userObject;
                User flowableUser = identityService.newUser(sysUser.getLoginName());
                flowableUser.setDisplayName(sysUser.getUserName());
                flowableUser.setEmail(sysUser.getEmail());
                //PWD_ 存放 用户电话号
                flowableUser.setPassword(sysUser.getPhonenumber());
                //FIRST_ 存放 用户ID
                flowableUser.setFirstName(sysUser.getUserId().toString());
                //LAST_存放部门ID
                flowableUser.setLastName(sysUser.getDeptId().toString());
                identityService.saveUser(flowableUser);
            }
        }
    }

    public void SyncSysPost(Object[] args, IdentityService identityService) {
        MappedStatement ms = (MappedStatement) args[0];
        String id = ms.getId();
        Object postObject = args[1];
        if (id.contains("deletePostByIds")) {
            if (postObject instanceof Map) {
                Map postIds = (Map) postObject;
                Long[] ids = (Long[]) postIds.get("array");
                for (Long postId : ids) {
                    Group flowableGroup = identityService.createGroupQuery().groupId(postId.toString()).singleResult();
                    if (flowableGroup != null) {
                        identityService.deleteGroup(flowableGroup.getId());
                    }
                }
            }
        } else if (id.contains("updatePost")) {
            if (postObject instanceof SysPost) {
                SysPost sysPost = (SysPost) postObject;
                Group flowableGroup = identityService.createGroupQuery().groupId(sysPost.getPostCode()).singleResult();
                if (flowableGroup == null) {
                    flowableGroup = identityService.newGroup(sysPost.getPostCode());
                } else {
                    flowableGroup.setId(sysPost.getPostCode());
                }
                flowableGroup.setName(sysPost.getPostName());
                flowableGroup.setType(sysPost.getPostId().toString());
                identityService.saveGroup(flowableGroup);
            }
        } else if (id.contains("insertPost")) {
            if (postObject instanceof SysPost) {
                SysPost sysPost = (SysPost) postObject;
                Group flowableGroup = identityService.newGroup(sysPost.getPostCode());
                flowableGroup.setName(sysPost.getPostName());
                flowableGroup.setType(sysPost.getPostId().toString());
                identityService.saveGroup(flowableGroup);
            }
        }
    }

    public void SyncSysUserPost(Object[] args, IdentityService identityService) {
        MappedStatement ms = (MappedStatement) args[0];
        ISysUserService sysUserService = SpringUtils.getBean(ISysUserService.class);
        ISysPostService sysPostService = SpringUtils.getBean(ISysPostService.class);
        ManagementService managementService=SpringUtils.getBean(ManagementService.class);
        String id = ms.getId();
        Object userPostObject = args[1];
        if (id.contains("batchUserPost")) {
            Map userPostObjectMap = (Map) userPostObject;
            List<SysUserPost> userPostList = (List<SysUserPost>) userPostObjectMap.get("list");
            for (SysUserPost userPost : userPostList) {
                SysUser sysUser = sysUserService.selectUserById(userPost.getUserId());
                SysPost sysPost = sysPostService.selectPostById(userPost.getPostId());
                User user=identityService.createUserQuery().userId(sysUser.getLoginName()).singleResult();
                Group group=identityService.createGroupQuery().groupId(sysPost.getPostCode()).singleResult();
                if (StringUtils.isNotEmpty(sysUser.getLoginName()) &&
                        StringUtils.isNotEmpty(sysPost.getPostCode())&&user!=null&&group!=null) {
                    identityService.createMembership(sysUser.getLoginName(), sysPost.getPostCode());
                }
            }
        }
        else  if (id.contains("deleteUserPostByUserId")) {
            Long userId = (Long) userPostObject;
            SysUser sysUser = sysUserService.selectUserById(userId);
            managementService.executeCommand(new DeleteMembershipByUserIdCmd(sysUser.getLoginName()));
        }
        else  if (id.contains("deleteUserPost")) {
            Map userIdMap = (Map) userPostObject;
            Long[] ids = (Long[]) userIdMap.get("array");
            for (Long userId : ids) {
                SysUser sysUser = sysUserService.selectUserById(userId);
                managementService.executeCommand(new DeleteMembershipByUserIdCmd(sysUser.getLoginName()));
            }

        }

    }
}
